home *** CD-ROM | disk | FTP | other *** search
/ BBS in a Box 5 / BBS in a Box -Volume V (BBS in a Box) (April 1992).iso / Files / Prog / A / About… 2.0.cpt / About… 2.0 Demo.p < prev    next >
Encoding:
Text File  |  1991-06-16  |  38.2 KB  |  1,227 lines  |  [TEXT/PJMM]

  1. program AboutDemo;                {    Last Update :  6/15/91 }
  2. {}
  3. {   This program demonstrates the About… 2.0 Unit. }
  4. {}
  5. {   About… is copyrighted, and I reserve all rights to it; both source and }
  6. {   compiled versions.  Please do not distribute modified copies without my }
  7. {   permission, or remove this notice.  Thanks. }
  8. {}
  9. {    About is being distributed as $10 shareware. Reigstered users receive a}
  10. {    diskette containing the Think Pascal source for the current version of}
  11. {    About… and may use it and future versions in any program or programs}
  12. {    you write.  You need not credit me for its use.}
  13. {}
  14. {   Jon Wind (About…)}
  15. {   2374 Hillwood Drive}
  16. {   Maplewood, MN  55119}
  17. {}
  18.  
  19.  
  20. { Modal procedure: }
  21. { this routine does everything, returning to calling proc only after the window is dismissed... }
  22. {•    procedure BuildAbout (WinRect: Rect;}
  23. {                            WinProc, TEXTid: Integer;}
  24. {                            WinTitle, WinMsg: Str255;}
  25. {                            WinMisc: AboutRec);}
  26.  
  27.  
  28. { Modeless procedures: }
  29. { returns true if the specified window is an About window; otherwise returns false }
  30. {•    function IsAboutWindow (theWindow: WindowPtr): Boolean;}
  31.  
  32. { open About window and return pointer to it - returns NIL if window is not created }
  33. { Note: you should keep track of this pointer only if you wish to keep specific track of it }
  34. {•    function OpenAbout (WinRect: Rect;}
  35. {                            WinProc, TEXTid: Integer;}
  36. {                               WinTitle, WinMsg: Str255;}
  37. {                            WinMisc: AboutRec): WindowPtr;}
  38.  
  39. { handle event relating to About window, ie updateEvt, activateEvt, mouseDown, keyDown, etc… }
  40. { Note: this proc should be called after every event for each About window for everything to work correctly }
  41. { Note: this proc calls the CloseAbout proc if the OK button is selected }
  42. { Note: you can filter events passed to it to simulate a modal dialog }
  43. {•    procedure HandleAbout (var theWindow: WindowPtr;}
  44. {                            var theEvent: EventRecord);}
  45.  
  46. { close the specified About window, kill data structures associated with it, and set theWindow to NIL… }
  47. { Note: this proc is called by the HandleAbout proc when an About window is dismissed by selecting its OK button }
  48. { Note: this proc should be called when the program needs to remove an About window }
  49. {•    procedure CloseAbout (var theWindow: WindowPtr);}
  50.  
  51.  
  52.     uses
  53.         About;                { …my unit! }
  54.  
  55.  
  56.     const
  57.         maxDemoWindows = 12;
  58.  
  59.         SharewareMsg = 'About… is $5 SHAREWARE.';
  60.         CopyrightMsg = '© 1989-91 by Jon Wind, All rights reserved';
  61.  
  62.         AboutDemoID = 128;
  63.         HelpTEXTID = 128;
  64.         AboutTEXTID = 1000;
  65.         IconID = 1000;
  66.         On = 1;
  67.         Off = 0;
  68.         Disable = 255;
  69.         goNext = 1;
  70.         goPrev = -1;
  71.  
  72. { *** The constants below were added to be used in the case statements.}
  73.         enterKey = 3;
  74.         BS = 8;
  75.         tabKey = 9;
  76.         CR = 13;
  77.         leftArrow = 28;
  78.         rightArrow = 29;
  79.         upArrow = 30;
  80.         downArrow = 31;
  81.         num0 = 48;
  82.         num1 = 49;
  83.         num2 = 50;
  84.         num3 = 51;
  85.         num4 = 52;
  86.         num5 = 53;
  87.         num6 = 54;
  88.         num7 = 55;
  89.         num8 = 56;
  90.         num9 = 57;
  91.         upperC = 67;
  92.         upperV = 86;
  93.         upperX = 88;
  94.         lowerC = 99;
  95.         lowerV = 118;
  96.         lowerX = 120;
  97.  
  98.         dTopEd = 5;
  99.         dLeftEd = 7;
  100.         dRightEd = 9;
  101.         dBottomEd = 11;
  102.         dSetRectBtn = 12;
  103.  
  104.         dBoxWRad = 13;
  105.         dPlainWRad = 14;
  106.         dAltWRad = 15;
  107.         dNoGrowRad = 16;
  108.         dRDocWRad = 17;
  109.  
  110.         dTitleEd = 24;
  111.         dMsgChk = 25;
  112.         dMsgEd = 26;
  113.  
  114.         dCenterRad = 27;
  115.         dTopWinRad = 28;
  116.         dMainMonRad = 29;
  117.  
  118.         dIconChk = 30;
  119.         dStylChk = 31;
  120.         dCopyChk = 32;
  121.         dCloseChk = 33;
  122.         dEquivChk = 34;
  123.         dModalChk = 35;
  124.  
  125.         dAboutBtn = 36;
  126.  
  127.     type
  128.         AuxWinPtr = ^AuxWinRec;
  129.         AuxWinHandle = ^AuxWinPtr;
  130.         AuxWinRec = record
  131.                 awNext: AuxWinHandle;        {handle to next AuxWinRec}
  132.                 awOwner: WindowPtr;         {ptr to window }
  133.                 awCTable: CTabHandle;        {color table for this window}
  134.                 dialogCItem: Handle;        {handle to dialog manager structures}
  135.                 awFlags: LONGINT;            {reserved for expansion}
  136.                 awReserved: CTabHandle;     {reserved for expansion}
  137.                 awRefCon: LONGINT;            {user Constant}
  138.             end;
  139.         DemoVars = record
  140.                 WinRect: Rect;
  141.                 BoxType, WinProc, Center: Integer;
  142.                 Msg, ShowIcon, Style, CopyIt, Close, Keys, Modal: Boolean;
  143.                 MsgText, TitleText: Str255;
  144.             end;
  145.  
  146.     var
  147.         AboutStuff: AboutRec;
  148.         CrossCurs: CursHandle;            { cross cursor handle }
  149.         MainDlgPtr: DialogPtr;                    { main dialog box pointer }
  150.         DemoWinPtr: array[1..maxDemoWindows] of WindowPtr;
  151.         zVar: DemoVars;
  152.         ramRect: Rect;
  153.         Finished: Boolean;
  154.         lastClick, ramDemand, ramFree: longint;
  155.  
  156.  
  157.  
  158.     function aNum2Str (aNum: LongInt): Str255;
  159. { NumToString procedure available as a function }
  160.         var
  161.             NumStr: Str255;
  162.     begin
  163.         NumToString(aNum, NumStr);
  164.         aNum2Str := NumStr;
  165.     end; { of func aNum2Str }
  166.  
  167.  
  168.     function aStr2Num (NumStr: Str255): Integer;
  169. { StringToNum procedure available as a function }
  170. { Note: won't accurately return numbers if > 32767 or if letters are in NumStr }
  171.         var
  172.             aNum: LongInt;
  173.     begin
  174.         StringToNum(Copy(NumStr, 1, 5), aNum);
  175.         if aNum < maxInt then
  176.             aStr2Num := aNum
  177.         else
  178.             aStr2Num := maxInt;
  179.     end; { of func aStr2Num }
  180.  
  181.  
  182.     function CtrlEnabled (theDialog: DialogPtr;
  183.                                     whichItem: Integer): Boolean;
  184.         var
  185.             thetype: Integer;
  186.             itmHdl: Handle;
  187.             itmrect: Rect;
  188.     begin
  189.         GetDItem(theDialog, whichItem, theType, itmHdl, itmrect);{ get button junk }
  190.         CtrlEnabled := (ControlHandle(itmHdl)^^.contrlHilite <> Disable);
  191.     end; { of proc CtrlEnabled }
  192.  
  193.  
  194.     procedure DrawDefaultBtn (theDialog: DialogPtr;
  195.                                     Item: Integer);
  196. {  outline default button in any dialog window }
  197.         var
  198.             theInt: Integer;
  199.             btnHdl: Handle;
  200.             thePen: PenState;
  201.             btnrect: Rect;
  202.     begin
  203.         SetPort(theDialog);                 { set window to current graf port }
  204.         GetPenState(thePen);                               { save current pen }
  205.         if (theDialog <> FrontWindow) | (not CtrlEnabled(theDialog, DialogPeek(theDialog)^.aDefItem)) then
  206.             PenPat(gray);
  207.         GetDItem(theDialog, DialogPeek(theDialog)^.aDefItem, theInt, btnHdl, btnrect);    { get item location }
  208.         Pensize(3, 3);                         { no wimpy button outlines here }
  209.         InsetRect(btnrect, -4, -4);               { set rectangle around button }
  210.         FrameRoundRect(btnrect, 16, 16);                     { draw the sucker! }
  211.         SetPenState(thePen);                                { restore old pen }
  212.     end; { of proc DrawDefaultBtn }
  213.  
  214.  
  215.  
  216.     function GetAuxWin (theWindow: WindowPtr;
  217.                                     var awHndl: AuxWinHandle): BOOLEAN;
  218.     inline
  219.         $AA42;
  220.  
  221.  
  222.     procedure FixWindowColor (theWindow: DialogPtr);
  223. { set window background color to match custom colored window content fill }
  224.         var
  225.             usedDefaultColors: Boolean;
  226.             theWorld: SysEnvRec;
  227.             RGBbackground: RGBColor;
  228.             awHndl: AuxWinHandle;
  229.             savePort: GrafPtr;
  230.     begin
  231.         if (SysEnvirons(1, theWorld) <> envNotPresent) then    { SysEnvirons call is available }
  232.             if theWorld.hasColorQD then        { has Color QuickDraw - OK to look for window color record… }
  233.                 begin
  234.                     GetPort(savePort);
  235.                     usedDefaultColors := GetAuxWin(theWindow, awHndl);
  236.                     RGBbackground := awHndl^^.awCTable^^.ctTable[cFrameColor].rgb;
  237.                     RGBBackColor(RGBbackground);        { set background to match wContentColor when drawing }
  238.                     SetPort(theWindow);
  239.                     EraseRect(theWindow^.portRect);
  240.                     SetPort(savePort);
  241.                 end;
  242.     end;  { of proc FixWindowColor }
  243.  
  244.  
  245.     procedure CenterWindow (theDialog: DialogPtr;
  246.                                     defaultbtn: Boolean);
  247. {  Center window - center higher for large screens - show, set port }
  248.         var
  249.             usedDefaultColors: Boolean;
  250.             theWorld: SysEnvRec;
  251.             RGBbackground: RGBColor;
  252.             awHndl: AuxWinHandle;
  253.     begin
  254.         SetPort(theDialog);                 { set window to current graf port }
  255.         with screenBits, theDialog^ do
  256.             MoveWindow(theDialog, ((bounds.right - bounds.left - portrect.right + portrect.left) div 2), ((bounds.bottom - bounds.top - portrect.bottom + portrect.top + 20) div 3), True);
  257.  
  258.         ShowWindow(theDialog);
  259.         FixWindowColor(theDialog);
  260.  
  261.         if defaultbtn then
  262.             DrawDefaultBtn(theDialog, 0);
  263.     end; { of proc CenterWindow }
  264.  
  265.  
  266.     procedure FakeClick (theDialog: DialogPtr;
  267.                                     theButton: Integer);
  268. {   select/deselect a button in a dialog }
  269.         var
  270.             theInt: Integer;
  271.             LInt: LongInt;
  272.             btnHdl: Handle;
  273.             btnrect: Rect;
  274.     begin
  275.         GetDItem(theDialog, theButton, theInt, btnHdl, btnrect);
  276.         HiliteControl(ControlHandle(btnHdl), 1);
  277.         Delay(8, LInt);
  278.         HiliteControl(ControlHandle(btnHdl), 0);
  279.     end; { of proc FakeClick }
  280.  
  281.  
  282.     procedure SetBtnTitle (theDialog: DialogPtr;
  283.                                     Btn: Integer;
  284.                                     Title: Str255);
  285. { update button title for dialog }
  286.         var
  287.             itmNum: Integer;
  288.             itmRect: Rect;
  289.             CurTitle: Str255;
  290.             itmHdl: Handle;
  291.     begin
  292.         GetDItem(theDialog, Btn, itmNum, itmHdl, itmRect);    { get button junk }
  293.         GetCTitle(ControlHandle(itmHdl), CurTitle);            { get current title }
  294.         if Title <> CurTitle then
  295.             SetCTitle(ControlHandle(itmHdl), Title);            { set title }
  296.     end; { of proc SetBtnTitle }
  297.  
  298.  
  299.     procedure GetSetBtn (theDialog: DialogPtr;
  300.                                     Btn, BtnState: Integer);
  301. { update button status for dialog }
  302.         var
  303.             itmNum: Integer;
  304.             itmrect: Rect;
  305.             itmHdl: Handle;
  306.     begin
  307.         GetDItem(theDialog, Btn, itmNum, itmHdl, itmrect);    { get button junk }
  308.         if BtnState <> Disable then
  309.             begin
  310.                 HiliteControl(ControlHandle(itmHdl), Off);        { enable control }
  311.                 SetCtlValue(ControlHandle(itmHdl), BtnState)    { set button state }
  312.             end
  313.         else
  314.             HiliteControl(ControlHandle(itmHdl), BtnState);    { disable control }
  315.     end; { of proc GetSetBtn }
  316.  
  317.  
  318.     function GetEdText (theDialog: DialogPtr;
  319.                                     Which: Integer): Str255;
  320. { return edit text contents }
  321.         var
  322.             itmNum: Integer;
  323.             itmrect: Rect;
  324.             itmHdl: Handle;
  325.             Msg: Str255;
  326.     begin
  327.         GetDItem(theDialog, Which, itmNum, itmHdl, itmrect);
  328.         GetIText(itmHdl, Msg);
  329.         GetEdText := Msg;
  330.     end; { of func GetEdText }
  331.  
  332.  
  333.     procedure ChangeChoiceText (theDialog: DialogPtr;
  334.                                     Which: Integer;
  335.                                     Msg: Str255);
  336. { change edit text contents }
  337.         var
  338.             itmNum: Integer;
  339.             itmrect: Rect;
  340.             itmHdl: Handle;
  341.     begin
  342.         if GetEdText(theDialog, Which) <> Msg then        { check current text before updating... }
  343.             begin
  344.                 GetDItem(theDialog, Which, itmNum, itmHdl, itmrect);
  345.                 SetIText(itmHdl, Msg);           { ...to avoid flicker }
  346.             end;
  347.     end; { of proc ChangeChoiceText }
  348.  
  349.  
  350.     procedure DoHelp;
  351. { Display modal help dialog - not a lot of code needed... }
  352.         var
  353.             HelpWinRect: Rect;
  354.             SavePort: GrafPtr;
  355.     begin
  356.         GetPort(SavePort);            { save current port }
  357.         SetPort(MainDlgPtr);
  358.         EraseRect(ramRect);        { memory count won't be accurate during modal display, so lose it }
  359.         InvalRect(ramRect);
  360.         with AboutStuff do        { set up the text stuff to be used by the About... unit }
  361.             begin
  362.                 FontInfo[AboutMsg].Font := Geneva;        { use Geneva for Message }
  363.                 FontInfo[AboutMsg].Size := 9;                { use 9 point for Message }
  364.                 FontInfo[AboutMsg].Face := [outline];        { use outline face for Message }
  365.                 FontInfo[AboutMsg].Color := GreenColor;    { use green for Message }
  366.                 FontInfo[AboutTEXT].Font := Monaco;        { use Monaco for TEXT - 'styl' resource may override }
  367.                 FontInfo[AboutTEXT].Size := 9;            { use 9 point for TEXT - 'styl' resource may override }
  368.                 FontInfo[AboutTEXT].Face := [bold];        { use bold face for TEXT - 'styl' resource may override }
  369.                 FontInfo[AboutTEXT].Color := RedColor;    { use red for TEXT - 'styl' resource may override }
  370.                 TEXTCopy := True;                    { allow copy to clipboard }
  371.                 KeyEquivs := True;                    { allow key equivalents }
  372.                 CloseBox := False;                    { set close box boolean }
  373.                 Styled := True;                        { set use of styled text (if possible) }
  374.                 CenterMode := AboutMainCenter;    { center window }
  375.                 MainIcon := 1000;                    { use icon }
  376.                 ClickIcon := AboutNoIcon;            { no new icon when original is clicked on - use MainIcon if only new message is desired }
  377.                 ClickMsg := '';                        { no click message - no need to define if ClickIcon = AboutNoIcon }
  378.             end;
  379.         SetRect(HelpWinRect, 0, 0, 420, 257);
  380.         BuildAbout(HelpWinRect, dBoxProc, HelpTEXTID, '', CopyrightMsg, AboutStuff);
  381.         SetPort(SavePort);            { save current port }
  382.     end;
  383.  
  384.  
  385.     function TabSelectText (theDialog: DialogPtr;
  386.                                     direction: Integer): Boolean;
  387.   { select the next, previous, or only edit text field }
  388.   { returns true if a field was found and selected }
  389.         var
  390.             thePtr: ^Integer;
  391.             x, theItem, totItems, itmtype: Integer;
  392.             itmHdl: Handle;
  393.             itmrect: Rect;
  394.     begin
  395.         TabSelectText := False;
  396.         theItem := 0;
  397.         x := Succ(DialogPeek(theDialog)^.editField);   { current edit text item }
  398.         if x = 0 then
  399.             Exit(TabSelectText);             { no edit text fields in dialog! }
  400.         thePtr := Pointer(DialogPeek(theDialog)^.Items^);
  401.         totItems := 1 + thePtr^;    { total # of items in dialog }
  402.         while theItem = 0 do
  403.             begin
  404.                 x := x + direction;
  405.                 if x > totItems then
  406.                     x := 1;   { reset index to first item }
  407.                 if x < 1 then
  408.                     x := totItems;   { reset index to last item }
  409.                 GetDItem(theDialog, x, itmtype, itmHdl, itmrect);  { get item's rect }
  410.                 if (itmtype = editText) or (itmtype = editText + itemDisable) then
  411.                     theItem := x; { found an edit text item }
  412.             end;
  413.         SelIText(theDialog, theItem, 0, maxint); { select ALL edit text }
  414.         TabSelectText := True;
  415.     end;  { of func TabSelectText }
  416.  
  417.  
  418.     procedure PutRectVarInDialog;
  419. { put current values into edit text boxes and set buttons }
  420.     begin
  421.         ChangeChoiceText(MainDlgPtr, dTopEd, aNum2Str(zVar.WinRect.top));
  422.         ChangeChoiceText(MainDlgPtr, dLeftEd, aNum2Str(zVar.WinRect.left));
  423.         ChangeChoiceText(MainDlgPtr, dRightEd, aNum2Str(zVar.WinRect.right));
  424.         ChangeChoiceText(MainDlgPtr, dBottomEd, aNum2Str(zVar.WinRect.bottom));
  425.     end; { of proc PutRectVarInDialog }
  426.  
  427.  
  428.     procedure FixCloseCheckbox;
  429.     begin
  430.         if (zVar.BoxType <> dNoGrowRad) & (zVar.BoxType <> dRDocWRad) then
  431.             begin
  432.                 GetSetBtn(MainDlgPtr, dCloseChk, Off);            { uncheck checkbox - no need to change zClose var though... }
  433.                 GetSetBtn(MainDlgPtr, dCloseChk, Disable);        { disable checkbox }
  434.             end
  435.         else
  436.             GetSetBtn(MainDlgPtr, dCloseChk, Ord(zVar.Close));    { restore checkbox to actual value }
  437.     end;{of proc FixCloseCheckbox }
  438.  
  439.  
  440.     procedure PutVarsInDialog;
  441. { put current values into edit text boxes and set buttons }
  442.     begin
  443.         GetSetBtn(MainDlgPtr, dMsgChk, Ord(zVar.Msg));                { set use message text checkbox }
  444.         GetSetBtn(MainDlgPtr, Succ(dCenterRad) + zVar.Center, On);    { set Center Window radio }
  445.         GetSetBtn(MainDlgPtr, dIconChk, Ord(zVar.ShowIcon));        { set Show Icon checkbox }
  446.         GetSetBtn(MainDlgPtr, dStylChk, Ord(zVar.Style));            { set use styled text checkbox }
  447.         GetSetBtn(MainDlgPtr, dCopyChk, Ord(zVar.CopyIt));            { set copy to clipboard checkbox }
  448.         GetSetBtn(MainDlgPtr, dCloseChk, Ord(zVar.Close));            { set close box checkbox }
  449.         GetSetBtn(MainDlgPtr, dEquivChk, Ord(zVar.Keys));            { set key equivalents checkbox }
  450.         PutRectVarInDialog;
  451.         ChangeChoiceText(MainDlgPtr, dTitleEd, zVar.TitleText);
  452.         ChangeChoiceText(MainDlgPtr, dMsgEd, zVar.MsgText);
  453.         SelItext(MainDlgPtr, dTopEd, 0, maxint);
  454.         GetSetBtn(MainDlgPtr, zVar.BoxType, On);            { set window type radio btn }
  455.     end; { of proc PutVarsInDialog }
  456.  
  457.  
  458.     procedure DrawFreeRam;
  459.         var
  460.             SavePort: GrafPtr;
  461.             fontStuff: FontInfo;
  462.             ramStr: Str255;
  463.     begin
  464.         GetPort(SavePort);            { save current port }
  465.         SetPort(MainDlgPtr);
  466.         ramFree := FreeMem;
  467.         NumToString(ramFree, ramStr);
  468.         EraseRect(ramRect);
  469.         TextSize(9);
  470.         TextFont(Geneva);
  471.         GetFontInfo(fontStuff);
  472.         MoveTo(ramrect.left, ramRect.bottom - fontStuff.descent);
  473.         DrawString(Concat(ramStr, ' bytes free'));
  474.         TextSize(12);
  475.         TextFont(0);
  476.         SetPort(SavePort);            { restore old port }
  477.     end;  { of proc DrawFreeRam }
  478.  
  479.  
  480.     function GetNextWinHdl: Integer;
  481.         var
  482.             j: SignedByte;
  483.     begin
  484.         GetNextWinHdl := 0;
  485.         for j := 1 to maxDemoWindows do
  486.             if DemoWinPtr[j] = nil then
  487.                 begin
  488.                     GetNextWinHdl := j;
  489.                     leave;
  490.                 end;
  491.     end;  { of func GetNextWinHdl }
  492.  
  493.  
  494.     procedure DemoAbout;
  495.         var
  496.             aWin: SignedByte;
  497.     begin
  498.         case zVar.BoxType of
  499.             dBoxWRad: 
  500.                 zVar.WinProc := dBoxProc;
  501.             dPlainWRad: 
  502.                 zVar.WinProc := plainDBox;
  503.             dAltWRad: 
  504.                 zVar.WinProc := altDBoxProc;
  505.             dNoGrowRad: 
  506.                 zVar.WinProc := noGrowDocProc;
  507.             dRDocWRad: 
  508.                 zVar.WinProc := rDocProc;
  509.         end;
  510.         with AboutStuff do        { set up the text stuff to be used by the About... unit }
  511.             begin
  512.                 FontInfo[AboutMsg].Font := 0;                    { use Chicago for Message }
  513.                 FontInfo[AboutMsg].Size := 0;                    { use 12 point for Message }
  514.                 FontInfo[AboutMsg].Face := [];                    { use normal face for Message }
  515.                 FontInfo[AboutMsg].Color := BlueColor;        { use blue for Message }
  516.                 FontInfo[AboutTEXT].Font := Geneva;            { use Geneva for TEXT - 'styl' resource may override }
  517.                 FontInfo[AboutTEXT].Size := 9;                { use 9 point for TEXT - 'styl' resource may override }
  518.                 FontInfo[AboutTEXT].Face := [];                { use normal face for TEXT - 'styl' resource may override }
  519.                 FontInfo[AboutTEXT].Color := GreenColor;    { use green for TEXT - 'styl' resource may override }
  520.                 TEXTCopy := zVar.CopyIt;            { set copy to clipboard boolean }
  521.                 KeyEquivs := zVar.Keys;            { set key equivalents boolean }
  522.                 CloseBox := zVar.Close;                { set close box boolean }
  523.                 Styled := zVar.Style;                    { set use of styled text (if possible) }
  524.                 CenterMode := zVar.Center;            { set center window integer }
  525.                 if zVar.ShowIcon then
  526.                     MainIcon := IconID
  527.                 else        { Note: use contant "AboutNoIcon" to indicate no icon }
  528.                     MainIcon := AboutNoIcon;
  529.                 ClickIcon := IconID + 1;
  530.                 ClickMsg := SharewareMsg;
  531.             end;
  532.         zVar.WinRect.top := aStr2Num(GetEdText(MainDlgPtr, dTopEd));
  533.         zVar.WinRect.left := aStr2Num(GetEdText(MainDlgPtr, dLeftEd));
  534.         zVar.WinRect.right := aStr2Num(GetEdText(MainDlgPtr, dRightEd));
  535.         zVar.WinRect.bottom := aStr2Num(GetEdText(MainDlgPtr, dBottomEd));
  536.         zVar.TitleText := GetEdText(MainDlgPtr, dTitleEd);
  537.         zVar.MsgText := GetEdText(MainDlgPtr, dMsgEd);
  538.  
  539.         PutRectVarInDialog;        { stuff rect values back into text fields }
  540.         SelItext(MainDlgPtr, Succ(DialogPeek(MainDlgPtr)^.editField), 0, 0);                { deselect text }
  541.  
  542. { find first available window pointer in array }
  543.         aWin := GetNextWinHdl;
  544.         if aWin > 0 then
  545.             begin
  546.                 if zVar.Msg then
  547.                     begin
  548.                         if zVar.Modal then
  549.                             begin
  550.                                 BuildAbout(zVar.WinRect, zVar.WinProc, AboutTEXTID, zVar.TitleText, zVar.MsgText, AboutStuff);
  551.                                 Exit(DemoAbout);
  552.                             end
  553.                         else
  554.                             DemoWinPtr[aWin] := OpenAbout(zVar.WinRect, zVar.WinProc, AboutTEXTID, zVar.TitleText, zVar.MsgText, AboutStuff)
  555.                     end
  556.                 else
  557.                     begin
  558.                         if zVar.Modal then
  559.                             begin
  560.                                 BuildAbout(zVar.WinRect, zVar.WinProc, AboutTEXTID, zVar.TitleText, '', AboutStuff);
  561.                                 Exit(DemoAbout);
  562.                             end
  563.                         else
  564.                             DemoWinPtr[aWin] := OpenAbout(zVar.WinRect, zVar.WinProc, AboutTEXTID, zVar.TitleText, '', AboutStuff);
  565.                     end;
  566.  
  567.                 if DemoWinPtr[aWin] <> nil then        { window was built }
  568.                     begin
  569.                         DrawFreeRam;
  570.  
  571.     { Disable OK button if there are no more window handles free }
  572.                         if GetNextWinHdl = 0 then
  573.                             begin
  574.                                 GetSetBtn(MainDlgPtr, OK, Disable);        { disable OK button since all handles are in use }
  575.                                 DrawDefaultBtn(MainDlgPtr, OK);
  576.                             end;
  577.                     end
  578.                 else
  579.                     SysBeep(3);        { window was not built }
  580.             end;
  581.     end;  { of proc DemoAbout }
  582.  
  583.  
  584.     procedure DealwithKeyDowns (var Event: EventRecord);
  585.         var
  586.             j: SignedByte;
  587.             theWindow, origWindow: WindowPtr;
  588.             theKey, FieldInUse, whichItem: Integer;
  589.             TEPeek: DialogPeek;
  590.             CmdKeyUsd: Boolean;
  591.             err: OSErr;
  592.     begin
  593.         theWindow := FrontWindow;
  594.  
  595.         if IsAboutWindow(theWindow) then
  596.             begin
  597.                 origWindow := theWindow;                            { save original window pointer }
  598.                 HandleAbout(theWindow, Event);
  599.                 if theWindow = nil then                            { About window was killed }
  600.                     for j := 1 to maxDemoWindows do                { remove entry window pointer array }
  601.                         if DemoWinPtr[j] = origWindow then
  602.                             begin
  603.                                 DemoWinPtr[j] := nil;
  604.                                 GetSetBtn(MainDlgPtr, OK, Off);            { enable OK button since at least one handle is not in use }
  605.                                 DrawDefaultBtn(MainDlgPtr, OK);
  606.                             end;
  607.             end
  608.         else if (GetWRefCon(theWindow) = AboutDemoID) then
  609.             begin
  610.                 whichItem := 0;
  611.                 TEPeek := DialogPeek(theWindow);
  612.                 FieldInUse := TEPeek^.editField + 1;        { get # of edit field in use }
  613.                 theKey := BitAnd(Event.message, charCodeMask);            { decode char }
  614.                 CmdKeyUsd := (BitAnd(Event.modifiers, cmdKey) <> 0);        { cmd key down? }
  615.                 if (FieldInUse <> dMsgEd) and (theKey = CR) then    { allow CRs in msg text field }
  616.                     theKey := enterKey;
  617.                 case theKey of
  618.                     enterKey:        { OK Button equivalents }
  619.                         begin
  620.                             whichItem := -1;        { hides key }
  621.                             if CtrlEnabled(theWindow, OK) then
  622.                                 begin
  623.                                     FakeClick(theWindow, OK);
  624.                                     DemoAbout;
  625.                                 end;
  626.                         end;
  627.                     lowerC, upperC:         { not needed with System 7.0! }
  628.                         if CmdKeyUsd then
  629.                             begin      { copy selection to clipboard }
  630.                                 DlgCopy(theWindow);
  631.                                 if TEGetScrapLen > 0 then
  632.                                     if ZeroScrap = noErr then
  633.                                         Err := TEtoScrap;
  634.                                 whichItem := -1;        { hides key }
  635.                             end
  636.                         else if FieldInUse <= dBottomEd then
  637.                             whichItem := -1;    { hides non-numeric keys }
  638.                     lowerV, upperV:          { not needed with System 7.0! }
  639.                         if CmdKeyUsd then
  640.                             begin      { paste clipboard }
  641.                                 Err := TEfromScrap;
  642.                                 if TEGetScrapLen > 0 then
  643.                                     DlgPaste(theWindow);
  644.                                 whichItem := -1;        { hides key }
  645.                             end
  646.                         else if FieldInUse <= dBottomEd then
  647.                             whichItem := -1;    { hides non-numeric keys }
  648.                     lowerX, upperX:          { not needed with System 7.0! }
  649.                         if CmdKeyUsd then
  650.                             begin      { cut selection to clipboard }
  651.                                 DlgCut(theWindow);
  652.                                 if TEGetScrapLen > 0 then
  653.                                     if ZeroScrap = noErr then
  654.                                         Err := TEtoScrap;
  655.                                 whichItem := -1;        { hides key }
  656.                             end
  657.                         else if FieldInUse <= dBottomEd then
  658.                             whichItem := -1;    { hides non-numeric keys }
  659.                     downArrow: 
  660.                         if TabSelectText(theWindow, goNext) then
  661.                             whichItem := -1;        { hides key }
  662.                     upArrow: 
  663.                         if TabSelectText(theWindow, goPrev) then
  664.                             whichItem := -1;        { hides key }
  665.                     tabKey: 
  666.                         if BitAnd(Event.modifiers, shiftKey) <> 0 then    { shift key down }
  667.                             if TabSelectText(theWindow, goPrev) then
  668.                                 whichItem := -1;        { hides key }
  669.                     otherwise
  670.                         if FieldInUse <= dBottomEd then
  671.                             if not (theKey in [num0..num9, BS, leftArrow, rightArrow]) then
  672.                                 whichItem := -1;    { hides non-numeric keys }
  673.                 end;
  674.                 if whichItem < 0 then
  675.                     Event.what := 0;      { 'EAT' processed cmd key }
  676.             end;
  677.  
  678.     end; { of proc DealwithKeyDowns }
  679.  
  680.  
  681.     function GetGrayRgn: RgnHandle;
  682. { get gray region }
  683.         var
  684.             thePtr: ^RgnHandle;
  685.     begin
  686.         thePtr := Pointer($9EE);
  687.         GetGrayRgn := thePtr^;
  688.     end;  { of func GetGrayRgn }
  689.  
  690.  
  691.     procedure rotateByte (p: Ptr);
  692.     inline
  693.         $205F, $1010, $E218, $1080;
  694. {        move.l  (sp)+,a0}
  695. {        move.b  (a0),d0}
  696. {        ror.b   #1,d0}
  697. {        move.b  d0,(a0)}
  698.  
  699.  
  700.     function ShiftDown: Boolean;
  701.         var
  702.             keys: keymap;
  703.     begin
  704.         GetKeys(keys);
  705.         if bittst(@keys, 63) then
  706.             shiftdown := True
  707.         else
  708.             shiftdown := False;
  709.     end;
  710.  
  711.  
  712.     procedure HandleSetRect (theDialog: DialogPtr);
  713. { deal with set rect for sample window }
  714.         var
  715.             j, itmType, winKind, totItems, height, width: Integer;
  716.             startPt, endPt: Point;
  717.             oldRect, titleRect: Rect;
  718.             deskPort: GrafPtr;
  719.             mouseEvent: EventRecord;
  720.             itmHdl: Handle;
  721.             rgnHdl: RgnHandle;
  722.             IntPtr: ^Integer;
  723.             marqueePat: Pattern;
  724.             lastDraw: LongInt;
  725.             theString: Str255;
  726.     begin
  727.         SelItext(theDialog, Succ(DialogPeek(theDialog)^.editField), 0, 0);                { deselect text }
  728.  
  729.         IntPtr := Pointer(DialogPeek(theDialog)^.Items^);
  730.         totItems := Succ(IntPtr^);        { total # of items in dialog }
  731.  
  732.         PenPat(gray);
  733.         PenMode(patBic);                    { to gray existing text... }
  734.         PaintRect(theDialog^.portRect);        { "gray out" text }
  735.         PenNormal;
  736.  
  737.         SetBtnTitle(theDialog, dSetRectBtn, 'Click');        { change btn title to help user & force btn redraw }
  738.         for j := 1 to 4 do                                        { redraw rect coordinates so they're not gray }
  739.             begin
  740.                 GetDItem(theDialog, (Pred(j) * 2) + dTopEd, itmType, itmHdl, oldRect);    { get button location }
  741.                 GetIText(itmHdl, theString);
  742.                 SetIText(itmHdl, theString);
  743.             end;
  744.         GetWTitle(theDialog, theString);
  745.         SetWTitle(theDialog, 'Click and Drag or Press a Key to Cancel');
  746.  
  747.     { here's a nasty hack that changes the window type to a dBoxProc type  so that the user will not }
  748.     { cause MultiFinder to switch to another window if an open window from another application is }
  749.     { clicked on (Note: Calling SetWTitle would cause the window to be redrawn as a dBoxProc window) }
  750.     { the window type is restored to its original setting later... }
  751.     { note: an alternate method would be to create a dBoxProc dialog beyond the edge of the screen }
  752.         winKind := HiWord(Ord(DialogPeek(theDialog)^.window.windowDefProc));{ save window type for later restore }
  753.         itmHdl := DialogPeek(theDialog)^.window.windowDefProc;
  754.         IntPtr := @itmHdl;
  755.         IntPtr^ := 256 * dBoxProc;        { use dBoxProc to stop MF switching }
  756.         DialogPeek(theDialog)^.window.windowDefProc := itmHdl;        { actually set window type}
  757.  
  758. { setup rect to use to gray title bar - bad idea since it may not work with alternate WDEFs...}
  759.         titleRect := theDialog^.portRect;
  760.         LocalToGlobal(titleRect.topLeft);
  761.         LocalToGlobal(titleRect.botRight);
  762.         OffsetRect(titleRect, 0, -18);
  763.         titleRect.bottom := titleRect.top + 16;
  764.  
  765.         GetDItem(theDialog, dSetRectBtn, itmType, itmHdl, oldRect);    { get button location }
  766.         LocalToGlobal(oldRect.topLeft);
  767.         LocalToGlobal(oldRect.botRight);
  768.  
  769.         New(deskPort);
  770.         OpenPort(deskPort);            { make grafport so can draw on screen }
  771.         UnionRgn(GetGrayRgn, deskPort^.visRgn, deskPort^.visRgn);        { add all monitors to visRgn of new grafPort }
  772.  
  773.     { here I remove the "Set" button from the clip region since I'll be changing its title and this }
  774.     { eliminates the possibility of gray line artifacts left from using the notPatXOr drawing mode }
  775.     { ...trust me... }
  776.         rgnHdl := NewRgn;
  777.         OpenRgn;
  778.         FrameRoundRect(oldRect, 16, 16);         { create button size region to remove from new grafPort }
  779.         CloseRgn(rgnHdl);
  780.         DiffRgn(deskPort^.clipRgn, rgnHdl, deskPort^.clipRgn);    { remove button from clip region }
  781.         DisposeRgn(rgnHdl);
  782.  
  783.         StuffHex(@marqueePat, '0F1E3C78F0E1C387');
  784.         lastDraw := 0;
  785.         oldRect := zVar.WinRect;
  786.  
  787.         PenMode(notPatXor);            { allows easy redrawing of gray frames }
  788.         SetCursor(CrossCurs^^);        { bring up cross cursor }
  789.         repeat
  790.             if (TickCount > lastDraw + 1) then
  791.                 begin
  792.                     lastDraw := TickCount;
  793.                     for j := 0 to 7 do                    { set up blinking marquee pattern by shifting bits }
  794.                         rotateByte(@marqueePat[j]);
  795.                     FrameRect(oldRect);        { erase old rect }
  796.                     PenPat(marqueePat);
  797.                     FrameRect(oldRect);        { draw new rect }
  798.                 end;
  799.         until GetNextEvent(mDownMask + keyDownMask, mouseEvent);        { wait for mousedown }
  800.         FrameRect(oldRect);        { erase old rect }
  801.         PenPat(gray);
  802.  
  803.         if mouseEvent.what = mouseDown then        { key stroke allows rect to be unchanged }
  804.             begin
  805.                 PenMode(patBic);
  806.                 PaintRect(titleRect);            { gray title bar - bad idea since it may not work with alternate WDEFs...}
  807.                 PenMode(notPatXor);        { allows easy redrawing of gray frames }
  808.  
  809.                 SetRect(oldRect, 0, 0, 0, 0);
  810.                 zVar.WinRect := oldRect;
  811.                 startPt := mouseEvent.where;        { globals are OK }
  812.  
  813.                 while stilldown do            { repeat until mouse button is released }
  814.                     begin
  815.                         GetMouse(endPt);
  816.  
  817.                         if (endPt.h > startPt.h) and (endPt.v > startPt.v) then
  818.                             SetRect(zVar.WinRect, startPt.h, startPt.v, endPt.h, endPt.v)
  819.                         else if (endPt.h > startPt.h) and (endPt.v < startPt.v) then
  820.                             SetRect(zVar.WinRect, startPt.h, endPt.v, endPt.h, startPt.v)
  821.                         else if (endPt.h < startPt.h) and (endPt.v > startPt.v) then
  822.                             SetRect(zVar.WinRect, endPt.h, startPt.v, startPt.h, endPt.v)
  823.                         else
  824.                             SetRect(zVar.WinRect, endPt.h, endPt.v, startPt.h, startPt.v);
  825.  
  826.                         if ShiftDown then                    { constrain rect to size of shortest side }
  827.                             with zVar.WinRect do
  828.                                 begin
  829.                                     height := bottom - top;
  830.                                     width := right - left;
  831.                                     if width > height then
  832.                                         if startPt.h = left then        { height < width }
  833.                                             right := left + height
  834.                                         else
  835.                                             left := right - height
  836.                                     else if startPt.v = top then    { width < height }
  837.                                         bottom := top + width
  838.                                     else
  839.                                         top := bottom - width
  840.                                 end;
  841.  
  842.                         if (zVar.WinRect.right - zVar.WinRect.left >= 150) and (zVar.WinRect.bottom - zVar.WinRect.top >= 100) then
  843.                             SetBtnTitle(theDialog, dSetRectBtn, 'OK')            { change btn title to help user }
  844.                         else
  845.                             SetBtnTitle(theDialog, dSetRectBtn, 'Drag');        { change btn title to help user }
  846.  
  847.                         if not EqualRect(oldRect, zVar.WinRect) then { update for new rect }
  848.                             begin
  849.                                 FrameRect(oldRect);    { erase old rect }
  850.                                 PutRectVarInDialog;    { update window rect display }
  851.                                 FrameRect(zVar.WinRect);    { draw current rect }
  852.                                 oldRect := zVar.WinRect;        { save current rect for later erasure }
  853.                             end;
  854.                     end;
  855.                 FrameRect(oldRect);        { erase last rect }
  856.             end;{ of mouseEvent.what = mouseDown }
  857.  
  858.         PenNormal;
  859.         InitCursor;                    { restore arrow cursor }
  860.         SetBtnTitle(theDialog, dSetRectBtn, 'Set');    { restore btn title }
  861.         ClosePort(deskPort);        { done with port - get rid of it }
  862.         Dispose(deskPort);
  863.         SetPort(theDialog);        { be sure main window is current window }
  864.  
  865.     { restore window type to original value }
  866.     { note: if a dBoxProc dialog was created beyond the edge of the screen, it should be disposed here }
  867.         itmHdl := DialogPeek(theDialog)^.window.windowDefProc;
  868.         IntPtr := @itmHdl;
  869.         IntPtr^ := winKind;
  870.         DialogPeek(theDialog)^.window.windowDefProc := itmHdl;
  871.  
  872.         SetWTitle(theDialog, theString);
  873.         InvalRect(theDialog^.portRect);
  874.     end;  { of proc HandleSetRect }
  875.  
  876.  
  877.     procedure DealwithDialogs (Event: EventRecord);
  878.         var
  879.             dlgPtr: DialogPtr;
  880.             itemHit, j, itmType, winKind, totItems: Integer;
  881.             err: OSErr;
  882.             ItemWasHit, fix: Boolean;
  883.     begin
  884.         case Event.what of
  885.             keydown, autokey: 
  886.                 begin
  887.                     DealwithKeyDowns(Event);
  888.                     if ((Event.what = keydown) | (Event.what = autokey)) & (DialogSelect(Event, dlgPtr, ItemHit)) then
  889.                         ;        { if Event was not altered by DealwithKeyDowns, pass key along to dialog manager }
  890.                 end;
  891.             ActivateEvt: 
  892.                 if GetWRefCon(WindowPtr(Event.message)) = AboutDemoID then
  893.                     DrawDefaultBtn(WindowPtr(Event.message), OK);
  894.             UpdateEvt: 
  895.                 begin
  896. {•     ItemWasHit := DialogSelect(Event, dlgPtr, ItemHit);•}
  897.                     BeginUpdate(MainDlgPtr);            { this method preserves the window's custom background color - if any }
  898.                     FixWindowColor(MainDlgPtr);
  899.                     DrawDialog(MainDlgPtr);
  900.                     EndUpdate(MainDlgPtr);
  901.                     DrawFreeRam;
  902.                 end;
  903.             otherwise
  904.                 if DialogSelect(Event, dlgPtr, ItemHit) & (GetWRefCon(dlgPtr) = AboutDemoID) then
  905.                     begin
  906.                         SetPort(dlgPtr);
  907.                         case itemHit of
  908.                             OK: 
  909.                                 DemoAbout;
  910.                             Cancel: 
  911.                                 Finished := True;
  912.                             dSetRectBtn:    { Set window rect }
  913.                                 HandleSetRect(dlgPtr);
  914.                             dBoxWRad..dRDocWRad:     { window types }
  915.                                 begin
  916.                                     ItemWasHit := ((itemHit = zVar.BoxType) & (TickCount - lastClick < GetDblTime));
  917.                                     GetSetBtn(dlgPtr, zVar.BoxType, Off);
  918.                                     fix := (zVar.BoxType <> itemHit);
  919.                                     zVar.BoxType := itemHit;
  920.                                     GetSetBtn(dlgPtr, zVar.BoxType, On);
  921.                                     if fix then
  922.                                         FixCloseCheckbox;
  923.                                     if ItemWasHit then
  924.                                         err := PostEvent(keyDown, enterKey);
  925.                                     lastClick := TickCount;
  926.                                 end;
  927.                             dMsgChk: 
  928.                                 begin
  929.                                     zVar.Msg := not zVar.Msg;
  930.                                     GetSetBtn(dlgPtr, itemHit, Ord(zVar.Msg));
  931.                                 end;
  932.                             dCenterRad..dMainMonRad: 
  933.                                 begin
  934.                                     ItemWasHit := ((itemHit - Succ(dCenterRad) = zVar.Center) & (TickCount - lastClick < GetDblTime));
  935.                                     GetSetBtn(MainDlgPtr, Succ(dCenterRad) + zVar.Center, Off);        { set Center Window radio }
  936.                                     zVar.Center := itemHit - Succ(dCenterRad);
  937.                                     GetSetBtn(MainDlgPtr, Succ(dCenterRad) + zVar.Center, On);            { set Center Window radio }
  938.                                     if ItemWasHit then
  939.                                         err := PostEvent(keyDown, enterKey);
  940.                                     lastClick := TickCount;
  941.                                 end;
  942.                             dIconChk: 
  943.                                 begin
  944.                                     zVar.ShowIcon := not zVar.ShowIcon;
  945.                                     GetSetBtn(dlgPtr, itemHit, Ord(zVar.ShowIcon));
  946.                                 end;
  947.                             dStylChk: 
  948.                                 begin
  949.                                     zVar.Style := not zVar.Style;
  950.                                     GetSetBtn(dlgPtr, itemHit, Ord(zVar.Style));
  951.                                 end;
  952.                             dCopyChk: 
  953.                                 begin
  954.                                     zVar.CopyIt := not zVar.CopyIt;
  955.                                     GetSetBtn(dlgPtr, itemHit, Ord(zVar.CopyIt));
  956.                                 end;
  957.                             dCloseChk: 
  958.                                 begin
  959.                                     zVar.Close := not zVar.Close;
  960.                                     GetSetBtn(dlgPtr, itemHit, Ord(zVar.Close));
  961.                                 end;
  962.                             dEquivChk: 
  963.                                 begin
  964.                                     zVar.Keys := not zVar.Keys;
  965.                                     GetSetBtn(dlgPtr, itemHit, Ord(zVar.Keys));
  966.                                 end;
  967.                             dModalChk: 
  968.                                 begin
  969.                                     zVar.Modal := not zVar.Modal;
  970.                                     GetSetBtn(dlgPtr, itemHit, Ord(zVar.Modal));
  971.                                 end;
  972.                             dAboutBtn:    { ? button }
  973.                                 DoHelp;
  974.                             otherwise
  975.                         end;
  976.                     end;
  977.         end;
  978.     end; { of proc DealwithDialogs }
  979.  
  980.  
  981.     procedure DealwithMouseDowns (Event: EventRecord);
  982.         var
  983.             j: SignedByte;
  984.             WindowPointedTo, theWindow: WindowPtr;
  985.             MouseLoc: Point;
  986.             WindoLoc: integer;
  987.     begin
  988.         MouseLoc := Event.Where;
  989.         WindoLoc := FindWindow(MouseLoc, WindowPointedTo);
  990.         if IsAboutWindow(WindowPointedTo) then
  991.             begin
  992.                 theWindow := WindowPointedTo;                    { save original window pointer }
  993.                 HandleAbout(WindowPointedTo, Event);
  994.                 if WindowPointedTo = nil then                    { About window was killed }
  995.                     for j := 1 to maxDemoWindows do                { remove entry from window pointer array }
  996.                         if DemoWinPtr[j] = theWindow then
  997.                             begin
  998.                                 DemoWinPtr[j] := nil;
  999.                                 GetSetBtn(MainDlgPtr, OK, Off);        { enable button }
  1000.                                 DrawDefaultBtn(MainDlgPtr, OK);
  1001.                             end;
  1002.             end
  1003.         else
  1004.             begin
  1005.                 case WindoLoc of
  1006.  
  1007.                     inMenuBar: 
  1008.                         ;
  1009.  
  1010.                     inSysWindow: 
  1011.                         ;
  1012.  
  1013.                     inContent: 
  1014.                         if WindowPointedTo <> FrontWindow then
  1015.                             begin
  1016.                                 SelectWindow(WindowPointedTo);            { bring to front }
  1017.                                 while WindowPointedTo <> nil do
  1018.                                     begin
  1019.                                         HandleAbout(WindowPointedTo, Event);        { pass event to About Unit }
  1020.                                         WindowPointedTo := WindowPtr(WindowPeek(WindowPointedTo)^.nextWindow);
  1021.                                     end;
  1022.                             end
  1023.                         else
  1024.                             begin {do something}
  1025.                                 sysbeep(1);
  1026.                             end;
  1027.  
  1028.                     inGrow: 
  1029.                         ;
  1030.  
  1031.                     InDrag:            { click in drag bar }
  1032.                         begin
  1033.                             DragWindow(WindowPointedTo, MouseLoc, ScreenBits.bounds);
  1034.                         end;
  1035.  
  1036.                     inGoAway: 
  1037.                         if TrackGoAway(WindowPointedTo, MouseLoc) then
  1038.                             DisposeWindow(WindowPointedTo); {since W mgr allocated space}
  1039.  
  1040.                     otherwise
  1041.                 end;{ of case}
  1042.             end;
  1043.     end; { of proc DealwithMouseDowns }
  1044.  
  1045.  
  1046.     procedure DealwithActivates (Event: EventRecord);
  1047.         var
  1048.             TargetWindow: WindowPtr;
  1049.     begin
  1050.         TargetWindow := WindowPtr(Event.message);
  1051.  
  1052.         if IsAboutWindow(TargetWindow) then
  1053.             HandleAbout(TargetWindow, Event)
  1054.         else
  1055.             begin
  1056.                 if Odd(Event.modifiers) then {then the window is becoming active}
  1057.                     begin
  1058.                         SetPort(TargetWindow);
  1059.        {and activate whatever else you need}
  1060.        {the scroll bars}
  1061.        {hilite selected text}
  1062.                     end
  1063.                 else
  1064.                     begin
  1065.        {deactivate whatever you need}
  1066.        {deactivate the scroll bars}
  1067.        {UNhilite selected text}
  1068.                     end;
  1069.             end;
  1070.     end; { of proc DealwithActivates }
  1071.  
  1072.  
  1073.     procedure DealwithUpdates (Event: EventRecord);
  1074.         var
  1075.             UpDateWindow: WindowPtr;
  1076.     begin
  1077.         UpdateWindow := WindowPtr(Event.message);
  1078.         if IsAboutWindow(UpdateWindow) then
  1079.             HandleAbout(UpdateWindow, Event)
  1080.         else
  1081.             begin
  1082.                 SetPort(UpdateWindow);      {set the port to one in Evt.msg}
  1083.                 BeginUpDate(UpdateWindow);
  1084.                 DrawDialog(UpdateWindow);
  1085.                 EndUpDate(UpdateWindow);
  1086.             end;
  1087.     end; { of proc DealwithUpdates }
  1088.  
  1089.  
  1090.     procedure MainEventLoop;
  1091.         var
  1092.             Event: EventRecord;
  1093.             ProcessIt: Boolean;
  1094.             NextWinPeek, WinPeek: WindowPeek;
  1095.     begin
  1096.         repeat
  1097.             PurgeMem(ramDemand);
  1098.             if (ramFree <> FreeMem) then
  1099.                 begin
  1100.                     SetPort(MainDlgPtr);
  1101.                     InvalRect(ramRect);
  1102.                 end;
  1103.  
  1104.             SystemTask;             {so you can support Desk Accessories}
  1105.             ProcessIt := GetNextEvent(EveryEvent, Event);
  1106.  
  1107.             if IsDialogEvent(Event) then
  1108.                 DealwithDialogs(Event)
  1109.             else if ProcessIt then{is true}
  1110.                 case Event.what of
  1111.  
  1112.                     mouseDown: 
  1113.                         DealwithMouseDowns(Event);
  1114.                     keydown, autokey: 
  1115.                         DealwithKeyDowns(Event);
  1116.                     ActivateEvt: 
  1117.                         DealwithActivates(Event);
  1118.                     UpDateEvt: 
  1119.                         DealwithUpdates(Event);
  1120.  
  1121.                     otherwise
  1122.                 end;{of Case}
  1123.         until Finished; {terminate the program}
  1124.  
  1125.  
  1126. { destroy any open About windows… }
  1127.         WinPeek := WindowPeek(FrontWindow);
  1128.         while WinPeek <> nil do
  1129.             begin
  1130.                 NextWinPeek := WinPeek^.nextWindow;    { if it's window is an About window, it's history - save next window pointer }
  1131.                 if IsAboutWindow(WindowPtr(WinPeek)) then    { is it an About window? }
  1132.                     begin
  1133.                         CloseAbout(WindowPtr(WinPeek));                { then kill it…}
  1134.                         DrawFreeRam;
  1135.                     end;
  1136.                 WinPeek := NextWinPeek;
  1137.             end;
  1138.  
  1139. { finally, destroy main dialog }
  1140.         DisposDialog(MainDlgPtr);
  1141.     end; { of proc MainEventLoop }
  1142.  
  1143.  
  1144.     function OpenColorDlg (dlgID: Integer): DialogPtr;
  1145. { open regular B&W or color dialog - allows for accurate display of custom content color }
  1146.         var
  1147.             hasColor: Boolean;
  1148.             theWorld: SysEnvRec;
  1149.             dlgPtr: DialogPtr;
  1150.             aRect: Rect;
  1151.             DITLhndl: Handle;
  1152.             WinTitle: Str255;
  1153.             procID: Integer;
  1154.     begin
  1155.         if (SysEnvirons(1, theWorld) <> envNotPresent) then    { SysEnvirons call is available }
  1156.             hasColor := theWorld.hasColorQD        { has Color QuickDraw }
  1157.         else
  1158.             hasColor := False;
  1159.  
  1160.         if hasColor then
  1161.             begin
  1162.                 dlgPtr := getNewDialog(dlgID, nil, Pointer(-1));    { get dialog box }
  1163.                 aRect := dlgPtr^.portRect;
  1164.                 GetWTitle(dlgPtr, WinTitle);
  1165.                 procID := GetWVariant(dlgPtr);        { GetWVariant func requires MacPlus or better }
  1166.                 DisposDialog(dlgPtr);
  1167.  
  1168.                 DITLhndl := Get1Resource('DITL', dlgID);
  1169.                 dlgPtr := NewCDialog(nil, aRect, WinTitle, False, procID, WindowPtr(nil), False, 0, DITLhndl);
  1170.             end
  1171.         else
  1172.             dlgPtr := getNewDialog(dlgID, nil, Pointer(-1));    { get B&W dialog box }
  1173.  
  1174.         OpenColorDlg := dlgPtr;
  1175.     end;  { of func OpenColorDlg }
  1176.  
  1177.  
  1178.     procedure Initialize;
  1179.         var
  1180.             j: SignedByte;
  1181.             aRect: Rect;
  1182.     begin
  1183.         CrossCurs := GetCursor(crosscursor);    { read in from system resource }
  1184.         HLock(Handle(CrossCurs));                    { lock the handle down }
  1185.  
  1186.         MainDlgPtr := OpenColorDlg(AboutDemoID);
  1187.         SetWRefCon(MainDlgPtr, AboutDemoID);        { store ID for use in distinguishing window later… }
  1188.  
  1189. { let Dialog Manager draw RoundRect around default btn }
  1190.         SetRect(aRect, 0, 0, 0, 0);
  1191.         SetDItem(MainDlgPtr, 3, userItem, @DrawDefaultBtn, aRect);
  1192.  
  1193.         for j := 1 to maxDemoWindows do
  1194.             DemoWinPtr[j] := nil;
  1195.  
  1196.         Finished := False;
  1197.         zVar.BoxType := dBoxWRad;
  1198.         zVar.Center := AboutNoCenter;
  1199.         zVar.Msg := True;
  1200.         zVar.ShowIcon := True;
  1201.         zVar.Style := True;
  1202.         zVar.CopyIt := True;
  1203.         zVar.Close := True;
  1204.         zVar.Keys := True;
  1205.         zVar.Modal := False;
  1206.         zVar.MsgText := Concat(AboutVersion, ' Unit', chr(13), CopyrightMsg);
  1207.         zVar.TitleText := Concat(AboutVersion, ' Demo');
  1208.         SetRect(zVar.WinRect, 22, 42, 456, 303);        { set default window rect }
  1209.  
  1210.         PutVarsInDialog;                                { put window rect values into edit text boxes }
  1211.         FixCloseCheckbox;
  1212.         CenterWindow(MainDlgPtr, True);            { center,display,set port,default btn }
  1213.  
  1214.         lastClick := TickCount;
  1215.         SetRect(ramRect, 1, 0, 120, 10);
  1216.         ramFree := 0;
  1217.         ramDemand := maxint * 10;
  1218.         InitCursor;
  1219.     end;  { of proc Initialize }
  1220.  
  1221.  
  1222. {main program loop}
  1223.  
  1224. begin
  1225.     Initialize;
  1226.     MainEventLoop;
  1227. end.